package montaltoNeds
import scala.util.Random
import montaltoFood._
import scala.collection.mutable.MutableList
import montaltoUtils._
import montaltoDirections._
/**
 * Created by IntelliJ IDEA.
 * User: Andrew Montalto
 * Date: Apr 19, 2010
 * Time: 12:26:25 PM
 * To change this template use File | Settings | File Templates.
 */
trait iNed{}

class Ned(pGeneticCode:GeneticCode)extends iNed{
  var isAlive:Boolean = true;
  var age:Int = 1
  var direction:Int = RandomSingleton.INSTANCE.nextPosInt(8)
  var gender:Gender = RandomGender
  val bag:Bag = new Bag()
  var currentCommand:Int = 0
  var moves = 0
  var mates = 0
  var turns = 0
  val geneticCode:GeneticCode = pGeneticCode;

  def RandomGender():Gender={
      val num:Int = RandomSingleton.INSTANCE.nextPosInt(2)
      if(num==0){
        return new Female
      }else {
        return new Male
      }
   }
  def getOlder(){
    age = age + 1
  }
  def turn={
    direction += 1
  }
  
  def moveToNextCommand = {
     this.currentCommand += 2  //goto next on
     this.currentCommand = currentCommand % 40 //start it over
  }
  def currentCommandString:String={
      return geneticCode.toString.substring(currentCommand, currentCommand+2)
  }
  def currentCommandSubStr:String={
      currentCommandString match {
        case "00" => {turns=turns+1;return "turn" }
        case "01" => {moves=moves+1;return "move" }
        case "10" => {return "mate" }
        case "11" => {return "mate" }
      }
  }
  def currentDirection:Direction= {
    return DirectionList.get(direction)
  }
  var executedCommand = false
  var hasMated= false
  def eat():Boolean = {
      if(isAlive){
        mustBurnCalories(age/10 + 1)
        return isAlive
      }else{
        return false
      }
  }

  //have to burn calories
  def mustBurnCalories(total:int)={
     if(!bag.use(scala.Math.floor(total).asInstanceOf[Int])){
        isAlive=false
    }
  }
  //optionally burn some calories
  def mightBurnCalories(total:int):Boolean={
     if(bag.currentCalories-total >= 0){
         mustBurnCalories(total)
         return true
     }else{
       return false
     }
  }
}

/**
 * class to hold food
 */
class Bag{
    val DEFAULT_CALORIES = 3
    private var totalCalories:Int = DEFAULT_CALORIES;
    def add(food:Food)={
      this.totalCalories += food.getCalories
    }
    def use(amount:Int):Boolean= {
      if(this.totalCalories - amount < 0){
        return false
      } else{
        this.totalCalories -= amount
        return true
      }
    }

    def currentCalories():Int={
      return totalCalories
    }

}

class GeneticCode{
    var theCode:String = ""
    val MAX_CODE_LEN = 40
    def generateRandom()={
      for(i <- 1 to MAX_CODE_LEN){
        theCode = theCode + RandomSingleton.INSTANCE.nextPosInt(2)
      }       
    }
    override def toString():String = {
      return theCode;
    }
    def custom(c:String){
      theCode = c
    }
}



trait Gender{
    def is():String

}
class Male extends Gender{
    def is():String={
      return "male"
    }
}
class Female extends Gender{
    def is():String={
      return "female"
    }
}

//ned builder pattern
object NedBuilder{

  def random():Ned={
     val gCode=new GeneticCode
     gCode.generateRandom
    
     return new Ned(gCode)

  }

}

